﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Dapper;

namespace GeneratInsertSQL.UI
{
    public partial class MainForm : Form
    {
        SynchronizationContext _context;
        public static MainForm Instance = null;
        Task _testTask;
        public MainForm()
        {
            InitializeComponent();
            _context = SynchronizationContext.Current;
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            try
            {
                validateInput();
                string sTableName = txtTableName.Text;
                string sKeyName = txtKeyName.Text;
                string sSQL = txtSQL.Text;
                _testTask = new Task(() =>
                {
                    _context.Send(x => { setUIReadOnly(true); }, null);
                    string result = doStart(sTableName, sKeyName, sSQL);
                    _context.Send(x =>
                    {
                        setUIReadOnly(false);
                        txtResult.Text = result;
                    }, null);
                });

                _testTask.Start();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace, "发生异常", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        public string doStart(string sTableName, string sKeyName, string sSQL)
        {
            try
            {
                SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["masterDb"].ToString());


                DataSet ds = new DataSet();
                using (SqlCommand cmd = new SqlCommand(sSQL, conn))
                {
                    using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
                    {
                        adapter.Fill(ds);
                    }
                }

                DataTable dt = ds.Tables[0];

                List<string> result = new List<string>();
                if (dt.Rows.Count == 0)
                {
                    throw new Exception("查询结果不能为空");
                }

                List<Column> columns = new List<Column>();
                foreach (DataColumn column in dt.Columns)
                {
                    columns.Add(new Column()
                    {
                        type = column.DataType.ToString(),
                        name = column.ToString()
                    });
                }
                string sColumns = "[" + string.Join("],[", columns.Select(p=>p.name).ToArray()) + "]";
                foreach (DataRow row in dt.Rows)
                {
                    result.Add($"DELETE FROM [{sTableName}] WHERE {sKeyName}='{row[sKeyName]}'");
                    result.Add($"INSERT INTO [{sTableName}]");
                    result.Add($"({sColumns})");
                    result.Add("VALUES(");
                    List<string> values = new List<string>();

                    foreach (var column in columns)
                    {
                        var cellValue = row[column.name];
                        if (cellValue == null)
                        {
                            values.Add("NULL");
                        }
                        else if (string.IsNullOrEmpty(cellValue.ToString())&& "System.Guid,System.DateTime".Contains(column.type))
                        {
                            values.Add("NULL");
                        }
                        else if (cellValue.ToString() == "System.Byte[]")
                        {
                            values.Add("NULL");
                        }
                        else
                        {
                            values.Add("'" + cellValue.ToString().Replace("'", "''") + "'");
                        }
                    }
                    result.Add(string.Join(",", values.ToList()));
                    result.Add(")");
                }

                return string.Join("\r\n", result);
            }
            catch (Exception ex)
            {
                return ex.Message + "\r\n" + ex.StackTrace;
            }
        }

        void setUIReadOnly(bool flag)
        {
            btnStart.Enabled = !flag;
            btnClose.Enabled = !flag;
            txtTableName.Enabled = !flag;
            txtKeyName.Enabled = !flag;
            txtSQL.Enabled = !flag;
            txtResult.Enabled = !flag;
        }

        void validateInput()
        {
            if (string.IsNullOrEmpty(txtTableName.Text))
            {
                throw new Exception("请录入表名");
            }
            if (string.IsNullOrEmpty(txtKeyName.Text))
            {
                throw new Exception("请录入主键");
            }
            if (string.IsNullOrEmpty(txtSQL.Text))
            {
                throw new Exception("请录入SQL");
            }
        }

        public static string GetDataTypeMap(string dataType)
        {
            switch (dataType)
            {
                case "String":
                case "SByte":
                case "TimeSpan":
                case "Char":
                case "Byte":
                case "Boolean":
                    return "varchar(200)";
                case "Guid": return "varchar(36)";
                case "Decimal":
                case "Double": return "decimal(18,4)";
                case "Int16":
                case "Int32":
                case "Int64":
                case "Single":
                case "UInt16":
                case "UInt32": return "int";
                case "DateTime": return "datetime";
                default: return "varchar(200)";
            }
        }
    }
}
